{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Working on a Windows 10\n", "Python version 3.11.8 | packaged by conda-forge | (main, Feb 16 2024, 20:40:50) [MSC v.1937 64 bit (AMD64)]\n", "Pandas version 2.2.3\n", "bifacial_radiance version 0.5.0b2.dev4+gedb973d.d20250924\n" ] } ], "source": [ "# This information helps with debugging and getting support :)\n", "import sys, platform\n", "import pandas as pd\n", "import bifacial_radiance as br\n", "print(\"Working on a \", platform.system(), platform.release())\n", "print(\"Python version \", sys.version)\n", "print(\"Pandas version \", pd.__version__)\n", "print(\"bifacial_radiance version \", br.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 4 - Debugging with Custom Objects\n", "## Fixed Tilt 2-up with Torque Tube + CLEAN Routine + CustomObject\n", "\n", "This journal has examples of various things, some which hav ebeen covered before and some in more depth:\n", "\n", "* Running a fixed_tilt simulation beginning to end.\n", "* Creating a 2-up module with torque-tube, and detailed geometry of spacings in xgap, ygap and zgap.\n", "* Calculating the tracker angle for a specific time, in case you want to use that value to model a fixed_tilt setup.\n", "* Loading and cleaning results, particularly important when using setups with torquetubes / ygaps. \n", "* Adding a \"Custom Object\" or **marker** at the Origin of the Scene, to do a visual sanity-check of the geometry. \n", "\n", "It will look something like this (without the marker in this visualization):\n", "\n", "\n", "\n", "***STEPS:***\n", "\n", "1. Specify Working Folder and Import Program \n", "2. Specify all variables \n", "3. Create the Radiance Object and generate the Sky \n", "4. Calculating tracker angle/geometry for a specific timestamp \n", "5. Making the Module & the Scene, Visualize and run Analysis \n", "6. Calculate Bifacial Ratio (clean results) \n", "7. Add Custom Elements to your Scene Example: Marker at 0,0 position " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Specify Working Folder and Import Program\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your simulation will be stored in C:\\Users\\cdeline\\Documents\\Python Scripts\\Bifacial_Radiance\\bifacial_radiance\\TEMP\\Tutorial_04\n" ] } ], "source": [ "import os\n", "from pathlib import Path\n", "\n", "testfolder = Path().resolve().parent.parent / 'bifacial_radiance' / 'TEMP' / 'Tutorial_04'\n", "\n", "# Another option using relative address; for some operative systems you might need '/' instead of '\\'\n", "# testfolder = os.path.abspath(r'..\\..\\bifacial_radiance\\TEMP') \n", "\n", "print (\"Your simulation will be stored in %s\" % testfolder)\n", "\n", "if not os.path.exists(testfolder):\n", " os.makedirs(testfolder)\n", "\n", "import bifacial_radiance\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Specify all variables for the module and scene\n", "\n", "Below find a list of all of the possible parameters for makeModule. \n", "scene and simulation parameters are also organized below. \n", "This simulation will be a complete simulation in terms of parameters that you can modify.\n", "\n", "The below routine creates a HEXAGONAL torque tube, for a 2-UP configuration of a specific module size. Parameters for the module, the torque tube, and the scene are below.\n", "This is being run with gendaylit, for one specific timestamp" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "simulationname = 'tutorial_4'\n", "\n", "## SceneDict Parameters\n", "gcr = 0.33 # ground cover ratio, = module_height / pitch\n", "albedo = 0.28 #'concrete' # ground albedo\n", "hub_height = 2.35 # we could also pass clearance_height. \n", "azimuth_ang = 90 # Modules will be facing East.\n", "lat = 37.5\n", "lon = -77.6\n", "nMods = 4 # doing a smaller array for better visualization on this example.\n", "nRows = 2 \n", "\n", "# MakeModule Parameters\n", "module_type='test-module'\n", "x = 1.996 # landscape, sinze x > y. Remember that orientation has been deprecated.\n", "y = 0.991\n", "tilt = 10\n", "numpanels = 2 # doing a 2-up system!\n", "\n", "\n", "# Gaps:\n", "xgap = 0.05 # distance between modules in the row.\n", "ygap = 0.15 # distance between the 2 modules along the collector slope.\n", "zgap = 0.175 # if there is a torquetube, this is the distance between the torquetube and the modules.\n", "# If there is not a module, zgap is the distance between the module and the axis of rotation (relevant for \n", "# tracking systems. \n", "\n", "# TorqueTube Parameters\n", "tubetype = 'Hex'\n", "diameter = 0.15\n", "material = 'Metal_Grey' # IT's NOT GRAY, IT's GREY.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Create the Radiance Object and generate the Sky" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "path = C:\\Users\\cdeline\\Documents\\Python Scripts\\Bifacial_Radiance\\bifacial_radiance\\TEMP\\Tutorial_04\n", "Making path: images\n", "Making path: objects\n", "Making path: results\n", "Making path: skies\n", "Making path: EPWs\n", "Making path: materials\n", "Loading albedo, 1 value(s), 0.280 avg\n", "1 nonzero albedo values.\n", "Getting weather file: USA_VA_Richmond.724010_TMY2.epw\n", " ... OK!\n", "8760 line in WeatherFile. Assuming this is a standard hourly WeatherFile for the year for purposes of saving Gencumulativesky temporary weather files in EPW folder.\n", "Coercing year to 2001\n", "Saving file EPWs\\metdata_temp.csv, # points: 8760\n", "Calculating Sun position for Metdata that is right-labeled with a delta of -30 mins. i.e. 12 is 11:30 sunpos\n" ] }, { "data": { "text/plain": [ "'skies\\\\sky2_37.5_-77.33_2001-06-17_1300.rad'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "demo = bifacial_radiance.RadianceObj(simulationname, path=str(testfolder)) # Create a RadianceObj 'object'\n", "demo.setGround(albedo) # input albedo number or material name like 'concrete'. To see options, run this without any input.\n", "epwfile = demo.getEPW(lat,lon) # pull TMY data for any global lat/lon\n", "metdata = demo.readWeatherFile(epwfile, coerce_year=2001) # read in the EPW weather data from above\n", "\n", "timestamp = metdata.datetime.index(pd.to_datetime('2001-06-17 13:0:0 -5')) # Make this timezone aware, use -5 for EST.\n", "demo.gendaylit(timestamp) # Mid-day, June 17th" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Calculating tracker angle/geometry for a specific timestamp\n", "\n", "This trick is useful if you are trying to use the fixed-tilt steps in bifacial_radiance to model a tracker for one specific point in time (if you take a picture of a tracker, it looks fixed, right? Well then). \n", "\n", "We assigned a 10 degree tilt at the beginning, but if we were to model a tracker as a fixed-tilt element because we are interested in only one point in time, this routine will tell us what tilt to use. *Please note that to model a tracker as fixed tilt, we suggest passing a hub_height, otherwise you will have to calculate the clearance_height manually.*\n", "\n", "
| \n", " | x | \n", "y | \n", "z | \n", "rearZ | \n", "mattype | \n", "rearMat | \n", "Wm2Front | \n", "Wm2Back | \n", "Back/FrontRatio | \n", "rearX | \n", "rearY | \n", "
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | \n", "1.029 | \n", "0.0 | \n", "2.710 | \n", "2.680 | \n", "a1.0.a0.test-module.6457 | \n", "a1.0.a0.test-module.2310 | \n", "909.867 | \n", "186.261 | \n", "0.205 | \n", "1.032 | \n", "0.0 | \n", "
| 1 | \n", "1.019 | \n", "0.0 | \n", "2.710 | \n", "2.680 | \n", "a1.0.a0.test-module.6457 | \n", "a1.0.a0.test-module.2310 | \n", "909.868 | \n", "186.047 | \n", "0.204 | \n", "1.021 | \n", "0.0 | \n", "
| 2 | \n", "1.008 | \n", "0.0 | \n", "2.709 | \n", "2.678 | \n", "a1.0.a0.test-module.6457 | \n", "a1.0.a0.test-module.2310 | \n", "909.868 | \n", "185.849 | \n", "0.204 | \n", "1.011 | \n", "0.0 | \n", "
| 3 | \n", "0.998 | \n", "0.0 | \n", "2.709 | \n", "2.678 | \n", "a1.0.a0.test-module.6457 | \n", "a1.0.a0.test-module.2310 | \n", "909.868 | \n", "185.635 | \n", "0.204 | \n", "1.000 | \n", "0.0 | \n", "
| 4 | \n", "0.987 | \n", "0.0 | \n", "2.707 | \n", "2.676 | \n", "a1.0.a0.test-module.6457 | \n", "a1.0.a0.test-module.2310 | \n", "909.868 | \n", "185.431 | \n", "0.204 | \n", "0.990 | \n", "0.0 | \n", "
| ... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
| 195 | \n", "-1.033 | \n", "0.0 | \n", "2.543 | \n", "2.512 | \n", "a1.0.a1.test-module.6457 | \n", "a1.0.a1.test-module.2310 | \n", "909.878 | \n", "185.560 | \n", "0.204 | \n", "-1.030 | \n", "0.0 | \n", "
| 196 | \n", "-1.043 | \n", "0.0 | \n", "2.541 | \n", "2.510 | \n", "a1.0.a1.test-module.6457 | \n", "a1.0.a1.test-module.2310 | \n", "909.878 | \n", "185.743 | \n", "0.204 | \n", "-1.040 | \n", "0.0 | \n", "
| 197 | \n", "-1.055 | \n", "0.0 | \n", "2.541 | \n", "2.510 | \n", "a1.0.a1.test-module.6457 | \n", "a1.0.a1.test-module.2310 | \n", "909.878 | \n", "185.958 | \n", "0.204 | \n", "-1.052 | \n", "0.0 | \n", "
| 198 | \n", "-1.064 | \n", "0.0 | \n", "2.540 | \n", "2.508 | \n", "a1.0.a1.test-module.6457 | \n", "a1.0.a1.test-module.2310 | \n", "909.878 | \n", "186.141 | \n", "0.205 | \n", "-1.062 | \n", "0.0 | \n", "
| 199 | \n", "-1.074 | \n", "0.0 | \n", "2.540 | \n", "2.508 | \n", "a1.0.a1.test-module.6457 | \n", "a1.0.a1.test-module.2310 | \n", "909.878 | \n", "186.144 | \n", "0.205 | \n", "-1.071 | \n", "0.0 | \n", "
200 rows × 11 columns
\n", "